//
// Created by baigui on 21-7-3.
//

#include <cstring>
#include <mediaStream.h>
#include <unistd.h>
#include <log.h>
#include <block.h>
#include "NDKDemux.h"

#define TAG "NDKDemux"

#include "media/NdkMediaCodec.h"

NDKDemux::NDKDemux(weak_ptr<MediaPlayer> player) : Demux(player) {

}

NDKDemux::~NDKDemux() {

    AMediaExtractor_delete(mMediaExtractor);
    if(mLooper)
        mLooper->quit();
}

bool NDKDemux::Open(void *path1) {
//    LOGV("Open! %s",path1);

    char *path = (char*)path1;
    mMediaExtractor = AMediaExtractor_new();
    media_status_t err = AMediaExtractor_setDataSource(mMediaExtractor, path);

    if (err != AMEDIA_OK) {
        LOGV("setDataSource error: %d", err);
        return false;
    }

    int numtracks = AMediaExtractor_getTrackCount(mMediaExtractor);

    LOGV("input has %d tracks", numtracks);
    bool selectVideo = false;
    bool selectAudio = false;
    for (int i = 0; i < numtracks; i++) {

        shared_ptr<MediaStream> stream = make_shared<MediaStream>();
        AMediaFormat *format = AMediaExtractor_getTrackFormat(mMediaExtractor, i);
        stream->formate = AMediaFormat_toString(format);
        const char *mime;
        stream->durationUs = AMediaFormat_getInt32(format,AMEDIAFORMAT_KEY_DURATION,0);
//        stream->track_id = AMediaFormat_getInt32(format,AMEDIAFORMAT_KEY_TRACK_ID,0);
//        stream->languge = AMediaFormat_getBuffer(format,AMEDIAFORMAT_KEY_LANGUAGE,0);
        if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) {
            LOGV("no mime type");
        } else if (!strncmp(mime, "video/", 6)) {
            LOGV("------- %s",AMediaFormat_toString(format));
            stream->id = i;
            stream->type = video;
            stream->mime = mime;
            AMediaFormat_getInt32(format,AMEDIAFORMAT_KEY_FRAME_RATE,&(stream->video.i_frame_rate));
            AMediaFormat_getInt32(format,AMEDIAFORMAT_KEY_WIDTH,&(stream->video.width));
           AMediaFormat_getInt32(format,AMEDIAFORMAT_KEY_HEIGHT,&(stream->video.height));
            if (selectVideo){
                stream->state = INIT;
                addStreamInfo(stream);
            } else{
                stream->state = SELCECT;
                addStreamInfo(stream);
                AMediaExtractor_selectTrack(mMediaExtractor, i);
                AMediaFormat_delete(format);
                break;
            }
            // Omitting most error handling for clarity.
            // Production code should check for errors.
        } else if (!strncmp(mime, "audio/", 6)){
            LOGV("get audio track");
//            stream->id = i;
//            stream->type = audio;
//            stream->mime = mime;
////            stream->languge = AMEDIAFORMAT_KEY_LANGUAGE
//            if (selectVideo){
//                stream->state = INIT;
//                addStreamInfo(stream);
//            } else{
//                stream->state = SELCECT;
//                addStreamInfo(stream);
//                AMediaExtractor_selectTrack(mMediaExtractor, i);
//            }
//            // Omitting most error handling for clarity.
//            // Production code should check for errors.

        }else{
            LOGV("other mine type");
        }
    }

    return true;
}

void NDKDemux::handle(int what, void* obj){
//    LOGV("------------looper start");
//    mLooper->post(DEMUX_REQUEST_BUFFER, nullptr,500);
    if(what == DEMUX_REQUEST_BUFFER){

        int read_size, total_size = 1000 * 1000;

        block_t *p = new block_t(total_size);

        p->setDataSize(0);
        int sampleSize = 0;

        uint8_t* b = p->getbuffer();
        do{
            read_size = AMediaExtractor_readSampleData(mMediaExtractor, b+sampleSize, total_size - sampleSize);
            if(read_size <= 0) {
                LOGV("why read size : %d  samplesize: %d",read_size,sampleSize);
                break;
            }

            bool ret = AMediaExtractor_advance(mMediaExtractor);
            if (!ret){
                LOGE("no more date");
                return;
            }
            sampleSize = read_size + sampleSize;
        }while (sampleSize < 0);
//        print(b+3,5);
//        LOGV("pocket size------------%d",sampleSize);
        p->setDataSize(sampleSize);

        if(p->getDataSize() > 0) {
            mPlayer.lock()->getVideoDecoder()->QueueBuffer(p);
        } else{
            delete p;
        }
        mLooper->post(DEMUX_REQUEST_BUFFER, nullptr,1);

    }

}

bool NDKDemux::start(){
    LOGV("------------ndk demux start");
    mLooper = make_shared<Looper>(shared_from_this());
    mLooper->post(DEMUX_REQUEST_BUFFER, this);
    return true;
}



void NDKDemux::requestbuffer() {
}
